function set-ntfsInheritance
{<#
.SYNOPSIS
Sets the permission inheritance for an ntfs folder
.DESCRIPTION
Sets the permission inheritance for an ntfs folder.
There are 3 settings, Allow (inherit permissions), BlockandCopy (block
inhertiance but copy inherited permisisons to folder) or BlockandRemove
(block inhertiance and remove all inherited permisisons.  In the case
of BlockandRemove,there is protection from the removal of all permissions.
Returns the acl of the folder if successful, $null if there was an error.
.NOTES
Function Name  	: set-ntfsInheritance
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
set D:\data to allow inherited permissions
set-ntfsInheritance -Path d:\data -inherit Allow
.EXAMPLE
set D:\data to block inherited permissions but copy them to the specified
Path (using positional parameters)
set-ntfsInheritance d:\data BlockandCopy
.EXAMPLE
set D:\data to block inherited permissions but copy them to the specified
UNC Path
set-ntfsInheritance -Path \\server\d$\data -inherit blockandcopy
.PARAMETER Path
Mandatory - The Path to the folder to set
Position 0
.PARAMETER Inherit
Mandatory - how inheritance will be configured - "BlockandRemove",
"BlockandCopy" or "Allow"
Position 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="unc Path to folder")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="The user or group to add")]
	[validateset("BlockandRemove","BlockandCopy","Allow")]
	[string] $inherit = "Allow"
)
process
{	try
{		if (Test-Path $Path)
{			$ACL = Get-Acl $Path
			switch($inherit)
{				"BlockandRemove"	
{					$Block = $true
					$copy = $false
					if ([string]::isnullorempty(($ACL.access | ? {$_.isinherited -eq $false})))
{						$cmdResult = add-ntfspermission $Path $($env:USERNAME) FullControl
						$ACL = Get-Acl $Path
					}
				}
				"BlockandCopy"		{$Block = $true;$copy = $true}
				"Allow"				{$Block = $false;$copy = $true}
			}			
			$acl.SetAccessRuleProtection($block,$copy)
			Set-Acl -AclObject $ACL -Path $Path
			return Get-Acl $Path
		}else{Write-Error "Invalid Path"}
	}catch{Write-Error $error[0]}
}
}
function get-NTFSPermission
{<#
.SYNOPSIS
Get NTFS permissions on a Path
.DESCRIPTION
Get NTFS permissions on a Path with the option to filter via inhereitence
or specific samaccountname
.NOTES
Function Name  	: get-NTFSPermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get all NTFS permission on d:\sales
get-NTFSPermission -Path d:\sales
.EXAMPLE
Get permission on d:\sales but exclude inherited permissions
get-NTFSPermission -Path d:\sales -inherited:$false
.EXAMPLE
Get permission on d:\sales but exclude samaccountnames adam and john
and also exclude inherited permissions
get-NTFSPermission -Path d:\sales -inherited:$false -exclude "adam","john"
.PARAMETER Path
Mandatory - The Path in which you want to return the ACL
Position 0
.PARAMETER inherited
Optional - filter inherited permissions
Position 1
.PARAMETER exclude
Optional - filter inherited permissions
Position 2
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="The Path in which you want to return the ACL")]
	[String] $Path,
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="filter inherited permissions")]
	[boolean] $Inherited = $true,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false,HelpMessage="Samaccountname of ID's to exclude")]
	$exclude = $null
)
PROCESS
{	$toreturn = @()
	if (-not $Inherited) {$ACL = (Get-Acl $Path).access | ? {$_.isinherited -eq $false}}
	else{$ACL = (Get-Acl $Path).access}
	if (-not [string]::IsNullOrEmpty($exclude))
{		foreach ($a in $acl)
{			$toadd = $true
			$exclude |%{if($a.IdentityReference.tostring().Split("\")[1] -eq $($_)){$toadd = $false}}
			if ($toadd){$toreturn += $a}
		}
		return $toreturn
	}else {return $acl}
}
}
function Add-NTFSPermission
{<#
.SYNOPSIS
Add an NTFS permission for a user or group to an ntfs folder
.DESCRIPTION
Add an NTFS permission for a user or group to an ntfs folder
Returns the acl of the folder if successful, $null if there was an error
.NOTES
Function Name  	: Add-NTFSPermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
give user adams full control to D:\data
Add-NTFSPermission -Path d:\data -object adams -Permission FullControl
.EXAMPLE
give group Sales modify to D:\data\sales
Add-NTFSPermission -Path d:\data\sales -object Sales -Permission Modify
.EXAMPLE
deny group Marketing modify to unc Path \\server\D$\data\sales
using positional parameters
Add-NTFSPermission \\server\D$\data\sales Marketing Modify -deny:$true
.EXAMPLE
give user adams custom permission read to D:\data
this just gives the read permission, whereas the read permission is actually
a group of permissions - read, list and execute file
Add-NTFSPermission -Path d:\data -object adams -Permission custom -custom read
.EXAMPLE
give group builtin administrators modify to D:\data\sales
Add-NTFSPermission -Path d:\data\sales -object administrators -domain builtin -Permission Modify
.EXAMPLE
give group sales modify to D:\data\sales using domain parameter
Add-NTFSPermission -Path d:\data\sales -object sales -domain NBdomain -Permission Modify
.EXAMPLE
give group sales modify to D:\data\sales using object parameter only
Add-NTFSPermission -Path d:\data\sales -object NBdomain\sales -Permission Modify
.PARAMETER Path
Mandatory - The Path to the folder to set
Position 0
.PARAMETER object
Mandatory - The object to assign the new permission
Position 1
.PARAMETER domain
Mandatory - The domain context of the object
Position 2
.PARAMETER Permission
Mandatory - The Permission to add - "Read","ReadSync","Modify" or "FullControl"
Position 3
.PARAMETER Deny
Optional - -deny:true is used to specify the permission being applied
is to deny the user or group.  if not specified, then value is false
Position 4
.PARAMETER Custom
Optional - this is used to add custom granular permission
Position 5
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="unc Path to folder")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="The user or group to add")]
	[alias("user")]
	[alias("group")]
	[string] $object,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false)]
	[string] $Domain = $($env:USERDOMAIN),		
	[Parameter(Mandatory=$true,Position=3,ValueFromPipeline=$false)]
	[validateset("Read","Modify","FullControl","custom")]
	[string] $Permission,
	[Parameter(Mandatory=$false,Position=4,ValueFromPipeline=$false)]
	[boolean] $Deny = $false,
	[Parameter(Mandatory=$false,Position=5,ValueFromPipeline=$false)]
	$custom = $null


)
process
{	if ($deny){$access = "Deny"}
	else{$access = "Allow"}
	$InheritContainerandObject=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
	$InheritNone=[System.Security.AccessControl.InheritanceFlags]::None
	$PropNone=[System.Security.AccessControl.PropagationFlags]::none
	try
{		if (Test-Path $Path)
{			$ACL = get-acl $Path
			if ($object -notmatch "\\"){$object = "$domain\$object"}
			###create default permission options
			$ReadRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::Read),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$listRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::ListDirectory),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$exRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::ExecuteFile),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$ModifyRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::Modify),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$FullRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::FullControl),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			switch ($Permission)
{				"Read"	
{					$ACL.AddAccessRule($ReadRule)
					$ACL.AddAccessRule($listRule)
					$ACL.AddAccessRule($exRule)
				}
				"custom"	
{					foreach ($rule in $custom)
{						try
{							$customRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::$rule),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
							$ACL.AddAccessRule($CustomRule)
						}catch{Write-Error "Error $_ occurred whilst processing custom permission $rule"}
					}
				}
				"Modify"	
{					$ModifyRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::Modify),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
					$ACL.AddAccessRule($ModifyRule)
				}
				"FullControl"	
{					$ACL.AddAccessRule($FullRule)
				}
			}
			set-acl -AclObject $ACL -Path $Path
			return $(get-acl $Path).access
		}else{Write-Error "Invalid Path"}
	}catch{Write-Error $error[0]}
}
}
function Remove-NTFSPermission
{<#
.SYNOPSIS
Remove an NTFS permission for a user or group to an ntfs folder
.DESCRIPTION
Remove an NTFS permission for a user or group to an ntfs folder
Returns the acl of the folder if successful, $null if there was an error
.NOTES
Function Name  	: Remove-NTFSPermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
remove user adams full control from D:\data
Remove-NTFSPermission -Path d:\data -object adams -Permission FullControl
.EXAMPLE
remove group Sales modify from D:\data\sales
Remove-NTFSPermission -Path d:\data\sales -object Sales -Permission Modify
.EXAMPLE
remove the deny group Marketing modify from unc Path \\server\D$\data\sales
using positional parameters
Remove-NTFSPermission \\server\D$\data\sales Marketing Modify -deny:$true
.EXAMPLE
remove user adams custom permission read to D:\data
this just gives the read permission, whereas the read permission is actually
a group of permissions - read, list and execute file
remove-NTFSPermission -Path d:\data -object adams -Permission custom -custom read
.PARAMETER Path
Mandatory - The Path to the folder to set
Position 0
.PARAMETER object
Mandatory - The object to assign the new permission
Position 1
.PARAMETER domain
Mandatory - The domain context of the object
Position 2
.PARAMETER Permission
Mandatory - The Permission to add - "Read","Modify" or "FullControl"
Position 3
.PARAMETER Deny
Optional - -deny:true is used to specify the permission being applied
is to deny the user or group.  if not specified, then value is false
Position 4
.PARAMETER Custom
Optional - this is used to add custom granular permission
Position 5
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="unc Path to folder")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="The user or group to add")]
	[alias("user")]
	[alias("group")]
	[string] $object,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false)]
	[string] $Domain = $($env:USERDOMAIN),
	[Parameter(Mandatory=$true,Position=3,ValueFromPipeline=$false)]
	[validateset("Read","Modify","FullControl","Custom")]
	[string] $Permission,
	[Parameter(Mandatory=$false,Position=4,ValueFromPipeline=$false)]
	[boolean] $Deny = $false,
	[Parameter(Mandatory=$false,Position=5,ValueFromPipeline=$false)]
	$custom = $null
)
process
{	if ($deny){$access = "Deny"}
	else{$access = "Allow"}
	$InheritContainerandObject=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
	$InheritNone=[System.Security.AccessControl.InheritanceFlags]::None
	$PropNone=[System.Security.AccessControl.PropagationFlags]::none
	try
{		if (Test-Path $Path)
{			$ACL = get-acl $Path
			if ($object -notmatch "\\"){$object = "$domain\$object"}
			$ReadRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::Read),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$listRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::ListDirectory),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$exRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::ExecuteFile),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$ModifyRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::Modify),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			$FullRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::FullControl),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
			switch ($Permission)
{				"Read"	
{					$cmdResult = $ACL.removeAccessRule($ReadRule)
					$cmdResult = $ACL.removeAccessRule($listRule)
					$cmdResult = $ACL.removeAccessRule($exRule)
				}
				"custom"	
{					foreach ($rule in $custom)
{						try
{							$customRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule($(New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $object),$([System.Security.AccessControl.FileSystemRights]::$rule),$InheritContainerandObject,$PropNone,$([System.Security.AccessControl.AccessControlType]::$access))
							$cmdResult = $ACL.removeAccessRule($CustomRule)
						}catch{Write-Error "Error $_ occurred whilst processing custom permission $rule"}
					}
				}
				"Modify"	
{					$cmdResult = $ACL.removeAccessRule($ModifyRule)
				}
				"FullControl"	
{					$cmdResult = $ACL.removeAccessRule($FullRule)
				}
			}
			set-acl -AclObject $ACL -Path $Path
			cmdResult $(get-acl $Path).access
		}else{Write-Error "Invalid Path"}
	}catch{Write-Error $error[0]}
}
}
function get-NTFSExplicitPermissions
{<#
.SYNOPSIS
Gets explicit NTFS permissions through a file system
.DESCRIPTION
Gets explicit NTFS permissions through a file system
Returns custom object with permission information if found.
Returns null and an error if nothing found.
.NOTES
Function Name  	: get-NTFSExplicitPermissions
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get Explicit NTFS permission for Path d:\data\group to 3 levels deep

get-NTFSExplicitPermissions -Path d:\data\group
.EXAMPLE
Get Explicit NTFS permission for Path d:\data\group to 3 levels deep
using positional parameters

get-NTFSExplicitPermissions d:\data\group
.EXAMPLE
Get Explicit NTFS permission for Path d:\data\group to 10 levels deep
using positional parameters

get-NTFSExplicitPermissions d:\data\group 10
.PARAMETER Path
Mandatory - The Path to the folder to get permissions
Postition 0
.PARAMETER recurse
Optional - the number of folder levels to recurse - defaults to 3
Postition 0
#>
param(
		[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="The Path in which you want to cmdResult the ACL")]
		[String] $Path,
		[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="number of levels to recurse")]
		[int]$recurse = 3
)
  get-NTFSPermission $Path -inherited:$false | Select-Object @{n="Path";e={$Path}},IdentityReference,FileSystemRights,AccessControlType
  if (-not [string]::IsNullOrEmpty($(dir $Path | ? {$_.psiscontainer -eq $true})) -and $recurse -gt 0)
{		foreach ($folder in $(dir $Path | ? {$_.psiscontainer -eq $true}))
{			  get-NTFSExplicitPermissions $($folder.fullname) $($recurse -1)
		}
  }
}
function new-FileShare
{<#
.SYNOPSIS
Create a new file share on specified server
.DESCRIPTION
Create a new file share on specified server
returns true if the folder has been created or already existed,
false if there was an error
.NOTES
Function Name  	: new-FileShare
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
create a new file share called sales on server1 in the Path d:\data
new-fileshare -name Sales -server server1 -Path d:\data
.EXAMPLE
create a new file share called sales on server1 in the Path d:\data
using positional parameters
new-fileshare Sales server1 d:\data
.PARAMETER Name
Mandatory - The Name of the share to create
Position 0
.PARAMETER server
Mandatory - the server to create the share on
Position 1
.PARAMETER Path
Mandatory - the Path to the parent of the folder that is going to be shared
Position 2
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the share to be created")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to host the share")]
	[string] $server,
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="Path to folder that is going to be shared")]
	[string] $Path
)
PROCESS
{	try
{		if (-not $(test-fileshare -name $Name -server $server))
{			$uncfolderPath = "\\$($server)\" + $($Path.Replace(":","$"))
			if (-not (Test-Path $uncfolderPath)){md $uncfolderPath}
			$Sharedfolder = "$uncfolderPath"
			if (-not (Test-Path $Sharedfolder)){md $Sharedfolder}
			$Share32 = [WMICLASS] "\\$server\Root\Cimv2:Win32_Share"
			$newshare = $Share32.Create("$Path",$Name,0,$null,"$Name")
			$returnvalue = $false
			switch ($newshare.returnvalue)
{				0	{write-host "Share created";$returnvalue = $true}
				2	{write-error "Access Denied";$returnvalue = $false}
				8	{write-error "Unknown Failure";$returnvalue = $false}
				9	{write-error "Invalid Name";$returnvalue = $false}
				10	{write-error "Invalid Level";$returnvalue = $false}
				21	{write-error "Invalid Parameter";$returnvalue = $false}
				22	{write-error "Duplicate Share";$returnvalue = $false}
				23	{write-error "Redirected Path";$returnvalue = $false}
				24	{write-error "Unknown Device or Directory";$returnvalue = $false}
				25	{write-error "Net Name Not Found";$returnvalue = $false}
			}
		}else{$returnvalue = $true;Write-warning "Share already exists"}
	}
	catch{Write-Error $error[0];$returnvalue = $false}
	cmdResult $returnvalue
}
}
function test-fileshare
{<#
.SYNOPSIS
Tests to see if the fileshare specified exists on the server
.DESCRIPTION
Tests to see if the fileshare specified exists on the server
returns true if the share exists or false if not
.NOTES
Function Name  	: test-FileShare
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
checks the existance of share1 on server1
test-fileshare -name share1 -server server1
.EXAMPLE
checks the existance of share1 on server1 using positional parameters
test-fileshare share1 server1
.PARAMETER Name
Mandatory - The Name of the share to create
Position 0
.PARAMETER server
Mandatory - the server to create the share on
Position 1
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the share to check")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to check for the share")]
	[string] $server
)
cmdResult $(get-wmiObject -Class win32_share -ComputerName $server -filter "Name='$Name'") -ne $null
}
function get-fileshares
{<#
.SYNOPSIS
Lists the fileshare on the specified server
.DESCRIPTION
Tests to see if the fileshare specified exists on the server
returns true if the share exists or false if not
.NOTES
Function Name  	: get-FileShares
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
list the file shares on server1
get-fileshares -server server1
.EXAMPLE
list the file shares on server1 using positional parameters
get-fileshares server1
.PARAMETER server
Mandatory - the server to create the share on
Position 0
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$false,HelpMessage="Name of the server to list shares")]
	[string] $server
)
cmdResult $(get-wmiObject -Class win32_share -ComputerName $server )
}
function set-sharepermission
{<#
.SYNOPSIS
Sets the permission of a share
.DESCRIPTION
Sets the permission of a share.  Being that permissions are primarily
controlled by NTFS, this function allows you to set the share
permissions to either the everyone or "Authenticated users" group.
The share permissions can be set to either read of modify.
please note that this function overwrites current permissions - it
does not append to the current permission set.
.NOTES
Function Name  	: set-sharepermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
set the share1 share on server1 to have share permission everyone - modify
set-sharepermission -name share1 -server server1 -object "everyone" -WriteEnable:$true
.EXAMPLE
set the share1 share on server1 to have share permission Authenticated Users - read
set-sharepermission -name share1 -server server1 -object "Authenticated Users"
.EXAMPLE
set the share1 share on server1 to have share permission Authenticated Users - modify
using positional parameters
set-sharepermission share1 server1 "Authenticated Users" -WriteEnable:$true
.PARAMETER Name
Mandatory - The Name of the share to set
Position 0
.PARAMETER server
Mandatory - the server to set the share permissions on
Position 1
.PARAMETER object
Mandatory - The group to set the permission to - "everyone" or "Authenticated Users"
Position 2
.PARAMETER WriteEnable
Optional - Enables the modify permission on the share. Default is false
Position 3
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of share to set permissions")]
	[alias("share")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server that host the share")]
	[string] $server,
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="The user or group to add")]
	[alias("user")]
	[alias("group")]
	[validateset("everyone","Authenticated Users")]
	[string] $object,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$false)]
	[boolean] $WriteEnable = $false
)
PROCESS
{	try
{		$share = get-wmiObject -Class win32_share -ComputerName $server -filter "Name='$Name'"

		if (test-fileshare -name $Name -server $server)
{			if ($WriteEnable){[int]$AM = 1245631}else{[int]$AM = 1179817}
			$ace = new-object system.management.managementclass Win32_ace
			$ace.psbase.SetPropertyValue("AccessMask",$AM)
			$ace.psbase.SetPropertyValue("AceType","0")
			$ace.psbase.SetPropertyValue("AceFlags","3")
			$Trustee = new-object system.management.managementclass win32_trustee
			switch ($object)
{				everyone	{[byte[]]$SID = @(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)}
				"Authenticated Users" {[byte[]]$SID = @(1, 1, 0, 0, 0, 0, 0, 5, 11, 0, 0, 0)}
			}
			$Trustee.psbase.SetPropertyValue("domain",$null)
			$Trustee.psbase.SetPropertyValue("Name",$object)
			$Trustee.psbase.SetPropertyValue("SID",$SID)			
			$ace.psbase.SetPropertyValue("trustee",$trustee.psobject.baseobject)
			$shareperms = new-object system.management.managementclass Win32_SecurityDescriptor
			$shareperms.psbase.SetPropertyValue("DACL",@($ace.psobject.baseobject))		
			$InvokeParams = $share.GetMethodParameters("setShareInfo")
			$InvokeParams["Access"]  =  $shareperms.psobject.baseobject
			$share.invokemethod("setshareInfo",$InvokeParams,$null)
			cmdResult $true
		}else{Write-Error "Share not found"}
	}catch{Write-Error $error[0];cmdResult $false}
}
}
function remove-fileshare
{<#
.SYNOPSIS
Removes a file share on specified server
.DESCRIPTION
Removes a file share on specified server
returns true if the share was removed or did not exist,
false if there was an error
.NOTES
Function Name  	: remove-FileShare
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
remove a file share called sales on server1
remove-fileshare -name Sales -server server1
.EXAMPLE
remove a file share called sales on server1
using positional parameters
remove-fileshare Sales server1
.PARAMETER Name
Mandatory - The Name of the share to create
Position 0
.PARAMETER server
Mandatory - the server to create the share on
Position 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the share to be created")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to host the share")]
	[string] $server
)
PROCESS
{	try
{		if ($(test-fileshare -name $Name -server $server))
{			$removeshare = (Get-WmiObject -Class Win32_Share -ComputerName $server -Filter "Name='$Name'").InvokeMethod("Delete",$null)
			$returnvalue = $false
			switch ($removeshare)
{				0	{write-host "Share $Name Removed";$returnvalue = $true}
				2	{write-error "Access Denied";$returnvalue = $false}
				8	{write-error "Unknown Failure";$returnvalue = $false}
				9	{write-error "Invalid Name";$returnvalue = $false}
				10	{write-error "Invalid Level";$returnvalue = $false}
				21	{write-error "Invalid Parameter";$returnvalue = $false}
				22	{write-error "Duplicate Share";$returnvalue = $false}
				23	{write-error "Redirected Path";$returnvalue = $false}
				24	{write-error "Unknown Device or Directory";$returnvalue = $false}
				25	{write-error "Net Name Not Found";$returnvalue = $false}
			}
		}else{$returnvalue = $True;Write-warning "Share not found"}
	}
	catch{Write-Error $error[0];$returnvalue = $false}
	cmdResult $returnvalue
}
}
function get-shareConnection
{<#
.SYNOPSIS
Get the current users that are connected to shares on a server
.DESCRIPTION
Get the current users that are connected to shares on a server.  This can be filtered to a specific share.
.NOTES
Function Name  	: get-shareConnection
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get all connections for all shares on server1
get-shareConnection -server Server1
.EXAMPLE
Get all connections for the users share on server1
get-shareConnection -server Server1 -sharename users
.EXAMPLE
Get all connections for the users share on server1 (using positional parameters)
get-shareConnection Server1 users
.PARAMETER server
Mandatory - The servername to connect to.
Postition 0
.PARAMETER sharename
Optional - sharename to cmdResult users connected to this share. Default is all shares
Postition 1
#>

	param
(
[Parameter(Position=0, Mandatory=$true,HelpMessage="Please enter a server Name")]
[string] $Server = "",
[Parameter(Position=1,Mandatory=$false)]
[alias("share")]
[string] $sharename = "all"
)
process
{try
{	$servershares = Get-WmiObject -ComputerName $Server -Class Win32_Share
	if ($sharename -eq "all"){$serverconnection = Get-WmiObject -ComputerName $Server -Class Win32_serverConnection}
	else
{		$cmd = "Get-WmiObject -ComputerName $Server -Class Win32_serverConnection -Filter `"Sharename = `'$sharename`'`""
		$serverconnection = Invoke-Expression $cmd
	}
	$users = @()
	foreach ($connection in $serverconnection)
{		$conn = "" | Select-Object "ip","user","share","SharePath"
		$conn.ip = $connection.Computername
		$conn.user = $connection.username
		$conn.share = $connection.sharename
		$conn.sharePath = ($servershares | ?{$_.Name -eq $connection.sharename}).Path
		$users += $conn
	}
	cmdResult $users
}catch{Write-Error $error[0]}
}

}
function get-diskspace
{<#
.SYNOPSIS
Get the current fixed disk space usage on the specified server.
.DESCRIPTION
Get the current fixed disk space usage on the specified server.
Returns the disk identifier, size, free space in Gb and
free space as a percentage
.NOTES
Function Name  	: get-diskspace
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get diskspace from server Server1
get-diskspace -server Server1
.EXAMPLE
Get diskspace from server Server1 using positional parameters
get-diskspace Server1
.PARAMETER server
Mandatory - The server Name to check diskspace.
Postition 0
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="The server to check the diskspace")]
	[string] $server
)
cmdResult $(Get-WmiObject -computer $server win32_volume | ? {$_.drivetype -eq 3 } | Select-Object @{Name="Servername";e={$server}},driveletter,@{Name="Size";e={[math]::round($_.capacity / 1gb,2)}},@{Name="FreeSpace";e={[math]::round($_.freespace / 1gb,2)}},@{Name="Freespace%";e={[math]::round(($($_.freespace / 1gb) / $($_.capacity / 1gb))*100,2)}})
}

#region DFS/DFS-R Functions

#region Get-DFSLink
function Get-DFSLink
{
<#
	.SYNOPSIS
		Get the specified Domain DFS link.

	.DESCRIPTION
		Get the specified Domain DFS link. Returns custom object with DFS link information if found. Returns null and an error if nothing found.

	.PARAMETER Path
		The DFS link path.

	.INPUTS

	.OUTPUTS

	.NOTES
		Function Name  	: Get-DFSLink
		Author     		: Adam Stone
		Requires   		: PowerShell V2

	.EXAMPLE
		Get dfs link \\domain\Root1\link1
		Get-DFSLink -Path \\domain\Root1\link1

	.EXAMPLE
		Get dfs link \\domain\Root1\link1 using positional parameters
		Get-DFSLink \\domain\Root1\link1

	.LINK
		http://adadmin.blogspot.com
#>
	[CmdletBinding(ConfirmImpact="Low")]
	param
	(
		[Parameter(
			Position = 0,
			Mandatory = $true,
			ValueFromPipeline = $true,
			HelpMessage = "Name of the DFS root to be returned.")]
		[Alias("Identity")]
		[string]$Path
	)

	$cmdResult = dfsutil link $Path;
	switch ($LASTEXITCODE)
	{
		0
		{
			$return			= "" | Select-Object Name,Path,State,Timeout,Targets;
			$return.Name	= $cmdResult[1].Split("=")[1].Split("`"")[1];
			$return.Path	= $Path;
			$return.State	= $cmdResult[1].Split("=")[2].Split("`"")[1];
			$return.Timeout	= $cmdResult[1].Split("=")[3].Split("`"")[1];

			$targetCheck = $true;
			$lineNo = 2;
			$targetCollection = @();
			while ($targetCheck)
			{
				if ($cmdResult[$lineNo] -match "Target")
				{
					$targetStore		= "" | Select-Object Path,State,Site;
					$targetStore.Path	= $cmdResult[$lineNo].Split(" ")[0].Split("=")[1].Replace('"', '');
					$targetStore.State	= $cmdResult[$lineNo].Split(" ")[1].Split("=")[1].Replace('"', '').Replace('ONLINE', 'Enabled').Replace('OFFLINE', 'Disabled');
					$targetStore.Site	= $cmdResult[$lineNo].Split(" ")[4].Replace(']', '');
					$targetCollection	+= $targetStore;
					$lineNo++;
				}
				else
				{
					$targetCheck = $false;
				}
			}
			$return.Targets = $targetCollection;
			return $return;
		}
		1168
		{
			Write-Warning "Namespace not found";
		}
		1707
		{
			Write-Error "Domain or Server Name not found";
		}
		default
		{
			Write-error "Command failed with error $LASTEXITCODE";
			$returnvalue = $false;
		}
	}
}
#endregion Get-DFSLink

#region Get-DFSLinkABEPermission
function Get-DFSLinkABEPermission
{
<#
	.SYNOPSIS
	Gets the DFS link ABE permissions
	.DESCRIPTION
	Gets the DFS link ABE permissions
	Returns custom object with DFS link ABE permissions if found.  Returns null and an
	error if nothing found.
	.PARAMETER Path
	Mandatory - The dfs link Path
	Postition 0
	.NOTES
	Function Name  	: Get-DFSLinkABEPermission
	Author     		: Adam Stone
	Requires   		: PowerShell V2
	.LINK
	http://adadmin.blogspot.com
	.EXAMPLE
	Get ABE permission for DFS link \\domain\Root1\link1
	Get-DFSLinkABEPermission -Path \\domain\Root1\link1
	.EXAMPLE
	Get ABE permission for DFS link \\domain\Root1\link1 using positional parameters
	Get-DFSLinkABEPermission \\domain\Root1\link1
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the share to check")]
	[alias("Identity")]
	[String] $Path
)

$cmdResult = dfsutil property sd $Path
switch ($LASTEXITCODE)
{	0	
{			$lineNo = 0
			$ObjectCollection = @()
			if ($cmdResult[0] -match "Security Descriptor is not associated with the link.")
{				Write-Host "No entries found"
				return $null
			}else
{				$check = $true
				while ($check)
{					if ($cmdResult[$lineNo] -match "$($env:userdomain)")
{						$return = "" | Select-Object Path,object,permission
						$return.Path = $Path
						if ($lineno -eq 0)
{							$return.object = $cmdResult[$lineNo].Split(" ")[1].Split(":")[0]
							$return.permission = $cmdResult[$lineNo].Split(" ")[1].Split(":")[1]
						}else
{							$return.object = $cmdResult[$lineNo].trim().Split(":")[0]
							$return.permission = $cmdResult[$lineNo].trim().Split(":")[1]							
						}
						$ObjectCollection += $return
						$lineNo++
					}else{$check = $false}
				}
				return $ObjectCollection
			}
		}
	1168{Write-error "Path not found"}
	1707{Write-Error "Domain or Server Name not found"}
	default {Write-error "command failed with error $LASTEXITCODE"}
}
}
#endregion Get-DFSLinkABEPermission

#region Get-DFSRoot
function Get-DFSRoot
{
<#
	.SYNOPSIS
		Get the specified Domain DFS root folder.

	.DESCRIPTION
		Get the specified Domain DFS root folder. Returns custom object with DFS root information if found. Returns null and an error if nothing found.

	.PARAMETER Name
		Name of the DFS root.

	.PARAMETER Server
		Name of the server or domain to connect to. Default is the current domain.

	.NOTES
		Function Name  	: Get-DFSRoot
		Author     		: Adam Stone
		Requires   		: PowerShell V2

	.EXAMPLE
		Get-DFSRoot Root1 from the current users domain
		Get-DFSRoot -name Root1

	.EXAMPLE
		Get-DFSRoot Root1 from the server Server1
		Get-DFSRoot -name Root1 -server Server1

	.EXAMPLE
		Get-DFSRoot Root1 from the domain domain1 using positional parameters
		Get-DFSRoot Root1 Domain1

	.LINK
		http://adadmin.blogspot.com
#>
	[CmdletBinding(ConfirmImpact="Low")]
	param
	(
		[Parameter(
			Position = 0,
			Mandatory = $true,
			ValueFromPipeline = $true,
			HelpMessage = "Name of the DFS root to be returned.")]
		[Alias("Identity")]
		[string]$Name,

		[Parameter(
			Position = 1,
			Mandatory = $false,
			ValueFromPipeline = $false,
			HelpMessage = "The server or domain hosting the namespace.")]
		[Alias("Domain")]
		[string]$Server = $($Env:USERDOMAIN)
	)

	$cmdResult = dfsutil root \\$Server\$Name;
	switch ($LASTEXITCODE)
	{
		0
		{
			$return			= "" | Select-Object Name,Version,Links,State,Timeout,Targets;
			$return.Name	= $cmdResult[3].Split(" ")[1].Split("=")[1].Replace('"', '');
			$return.Version	= $cmdResult[0].Split(" ")[0];
			$return.Links	= $cmdResult[0].Split(" ")[-2];

			$state = 2;
			while ($cmdResult[3].Split(" ")[$state].Split("=")[0] -ne "State")
			{
				$state ++;
			}
			$return.State = $cmdResult[3].Split(" ")[$state].Split("=")[1].Replace('"', '');

			$timeout = 3;
			while ($cmdResult[3].Split(" ")[$timeout].Split("=")[0] -ne "Timeout")
			{
				$timeout++;
			}
			$return.Timeout = $cmdResult[3].Split(" ")[$timeout].Split("=")[1].Replace('"', '');

			$targetCheck = $true;
			$lineNo = 4;
			$targetCollection = @();
			while ($targetCheck)
			{
				if ($cmdResult[$lineNo] -match "Target")
				{
					$targetStore		= "" | Select-Object Server,State,Site;
					$targetStore.Server	= $cmdResult[$lineNo].Split(" ")[0].Split("=")[1].Replace('"', '').Split("\")[2];
					$targetStore.State	= $cmdResult[$lineNo].Split(" ")[1].Split("=")[1].Replace('"', '');
					$targetStore.Site	= $cmdResult[$lineNo].Split(" ")[4].Replace(']','');
					$targetCollection	+= $targetStore;
					$lineNo++;
				}
				else
				{
					$targetCheck = $false;
				}
			}
			$return.Targets = $targetCollection;
			return $return;
		}
		1168
		{
			Write-Warning "Namespace not found";
		}
		1707
		{
			Write-Error "Domain or Server Name not found";
		}
		default
		{
			Write-Error "Command failed with error $LASTEXITCODE";
			$returnvalue = $false;
		}
	}
}
#endregion Get-DFSRoot

function New-DfsRoot

{<#
.SYNOPSIS
Create the specified Domain DFS root folder
.DESCRIPTION
Create the specified Domain DFS root folder.
Returns custom object with DFS root information if found.  Returns null and an error if
the create failed.  With create a share on the specified server if one doesn't exist
.NOTES
Function Name  	: New-DfsRoot
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
create domain based dfsroot Root1 on server1 in Path d:\data
New-DfsRoot -name Root1 -server Server1 -parentPath d:\data -description "New root 1"
.EXAMPLE
create standalone dfsroot Root1 on server1 in Path d:\data
New-DfsRoot -name Root1 -server Server1 -parentPath d:\data -description "New root 1" -standalone:$true
.EXAMPLE
create domain based dfsroot Root1 on server1 in Path d:\data using positional parameters
New-DfsRoot Root1 Server1 d:\data
.EXAMPLE
create domain based dfsroot Root1 on server1 in Path d:\data as a version 1 namespace
New-DfsRoot -name Root1 -server Server1 -parentPath d:\data -description "New root 1" -version V1
.PARAMETER Name
Mandatory - The dfsroot Name
Postition 0
.PARAMETER server
Mandatory - Name of the server to host the root on.
Postition 1
.PARAMETER parentPath
Mandatory - The Path to create the dfs root share
Postition 2
.PARAMETER description
Oprional - Name of the server to host the root on.
Postition 3
.PARAMETER version
optional - the version of the domain based namespace - accepts "v1" or "v2".
Postition 4
.PARAMETER standalone
optional - configures the namespace to be stand alone rather
than domain based - accepts $true or $false.
Postition 5
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the dfs root to be created")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to host the dfs root")]
	[string] $server,
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="The Path to create the dfs root share")]
	[string] $parentPath,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$false,HelpMessage="A comment or description to add to the root")]
	[string] $description = "",
	[Parameter(Mandatory=$false,Position=4,ValueFromPipeline=$false,HelpMessage="Set the version of the namesapce")]
	[validateset("V1","V2")]
	[string] $version = $null,
	[Parameter(Mandatory=$false,Position=5,ValueFromPipeline=$false,HelpMessage="Configure the namespace to be standalone")]
	[boolean] $Standalone = $false
)
PROCESS
{	$returnvalue = $false
	try
{		$sharecreated = new-fileshare -name $Name -server $server -Path "$parentPath\$Name"
		if ($sharecreated)
{			if (-not $Standalone)
{			$cmd = "dfsutil root adddom \\$server\$Name"
			if (-not [string]::IsNullOrEmpty($version)){$cmd = $cmd + " $version `"$description`""}else {$cmd = $cmd + " `"$description`""}
			}else{$cmd = "dfsutil root addstd \\$server\$Name `"$description`""}
			if ($(Invoke-Expression $cmd) -match "The given root already exists."){write-Warning "DFSroot folder $Name already exists.  Use add-DFSRootTarget to add server to root"}
			switch ($LASTEXITCODE)
{				0	{$returnvalue = $true}
				1707{Write-Error "Domain or Server Name not found"}
				1168{Write-Error "share not found"}
				161{Write-Error "Path directory overlaps an existing root. The DFS Root will not be created"}
				default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
			}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){Get-dfsroot $Name $server}
	else{return $null}
}
}

function add-DFSRootTarget
{<#
.SYNOPSIS
Add a server to a Domain DFS root
.DESCRIPTION
Add a server to a Domain DFS root
Returns custom object with DFS root information if found.  Returns null and an error if
the Add failed.  With create a share on the specified server if one doesn't exist
.NOTES
Function Name  	: add-DFSRootTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Add server Server1 to dfsroot Root1 hosting the dfs root share in d:\data
add-DFSRootTarget -name Root1 -server Server1 -parentPath d:\data
.EXAMPLE
Add server Server1 to dfsroot Root1 hosting the dfs root share in d:\data
using positional parameters
add-DFSRootTarget Root1 Server1 d:\data
.PARAMETER Name
Mandatory - The dfsroot Name
Postition 0
.PARAMETER server
Mandatory - Name of the server to add to the root.
Postition 1
.PARAMETER parentPath
Mandatory - The Path to create the dfs root share
Postition 2
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the dfs root to be created")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to host the dfs root")]
	[string] $server,
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="The Path to host the dfs root")]
	[string] $parentPath
)
PROCESS
{	$returnvalue = $false
	try
{		$sharecreated = new-fileshare -name $Name -server $server -Path $parentPath
		if ($sharecreated)
{			$cmdResult = dfsutil target add \\$server\$Name
			switch ($LASTEXITCODE)
{				0	{$returnvalue = $true}
				183 {write-Warning "Server already a target of the namespace";$returnvalue = $true}
				default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
			}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-dfsroot $Name $($env:USERDOMAIN)}
	else{return $null}
}
}
function remove-DFSRoottarget
{<#
.SYNOPSIS
Remove a server from a Domain DFS root
.DESCRIPTION
Remove a server from a Domain DFS root
Returns custom object with DFS root information if found.  Returns null and an error if
the remove failed.
.NOTES
Function Name  	: Remove-DFSRootTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Remove server Server1 to dfsroot Root1
Remove-DFSRootTarget -name Root1 -server Server1
.EXAMPLE
Remove server Server1 to dfsroot Root1 using positional parameters
Remove-DFSRootTarget Root1 Server1
.PARAMETER Name
Mandatory - The dfsroot Name
Postition 0
.PARAMETER server
Mandatory - Name of the server to remove from the root.
Postition 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the dfs root to be created")]
	[alias("Identity")]
	[String] $Name,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Name of the server to host the dfs root")]
	[string] $server		
)
PROCESS
{	$returnvalue = $false
	try
{
		$cmdResult = dfsutil target remove \\$server\$Name
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1168{write-Warning "Server not a target of the namespace";$returnvalue = $false}
			1707{Write-Error "Domain or Server Name not found";$returnvalue = $false}
			default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
		}

	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-dfsroot $Name $($env:USERDNSDOMAIN)}
	else{return $null}
}
}
function get-DFSRootABEStatus
{<#
.SYNOPSIS
Get the status of Access Based Enumeration for a DFS root
.DESCRIPTION
Get the status of Access Based Enumeration for a DFS root
Returns either enabled or disabled for a valid Path. Returns null and an error if
the an error was encountered.
.NOTES
Function Name  	: get-DFSRootABEStatus
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Rget ABE status for dfsroot Path \\domain\root1emove server Server1 to dfsroot Root1
get-DFSRootABEStatus -Path \\domain\root1
.EXAMPLE
get ABE status for dfsroot Path \\domain\root1 using positional parameters
get-DFSRootABEStatus \\domain\root1
.PARAMETER Name
Mandatory - The dfsroot Path
Postition 0
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the share to check")]
	[alias("Identity")]
	[String] $Path
)
try{return (dfsutil property abe $Path)[0].Split(" ")[-1]}
catch{Write-Error $error[0]}
}
function enable-DFSrootABE
{<#
.SYNOPSIS
Enable Access Based Enumeration for a DFS root
.DESCRIPTION
Enable Access Based Enumeration for a DFS root
Returns either enabled or disabled for a valid Path. Returns null and an error if
the an error was encountered.
.NOTES
Function Name  	: enable-DFSrootABE
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
enable ABE for dfsroot Path \\domain\root1
enable-DFSrootABE -Path \\domain\root1
.EXAMPLE
enable ABE for dfsroot Path \\domain\root using positional parameters
enable-DFSRootABE \\domain\root1
.PARAMETER Name
Mandatory - The dfsroot Path
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the dfs root to be enabled")]
	[alias("Identity")]
	[String] $Path
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property abe enable $Path
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found";$returnvalue = $false}
			1168{Write-Error "DFS Name spcae not found";$returnvalue = $false}
			default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
		}

	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return get-DFSRootABEStatus $Path}
	else{return $null}
}
}
function disable-DFSrootABE
{<#
.SYNOPSIS
Disable Access Based Enumeration for a DFS root
.DESCRIPTION
Disable Access Based Enumeration for a DFS root
Returns either enabled or disabled for a valid Path. Returns null and an error if
the an error was encountered.
.NOTES
Function Name  	: Disable-DFSrootABE
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Disable ABE for dfsroot Path \\domain\root1
Disable-DFSrootABE -Path \\domain\root1
.EXAMPLE
Disable ABE for dfsroot Path \\domain\root using positional parameters
Disable-DFSRootABE \\domain\root1
.PARAMETER Name
Mandatory - The dfsroot Path
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the dfs root to be enabled")]
	[alias("Identity")]
	[String] $Path
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property abe disable $Path
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found";$returnvalue = $false}
			1168{Write-Error "DFS Name spcae not found";$returnvalue = $false}
			default {Write-error "command failed with error $LASTEXITCODE";write-host $cmdResult;$returnvalue = $false}
		}

	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return get-DFSRootABEStatus $Path}
	else{return $null}
}
}

function get-DFSroots
{<#
.SYNOPSIS
Get all DFS roots for a domain
.DESCRIPTION
Get all DFS roots for a domain
Returns custom object with all DFS root information if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: get-DFSroots
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get all DFS roots for domain domain.com
get-DFSroots -domain domain.com
.EXAMPLE
Get all DFS roots for domain domain.com using positional parameters
get-DFSroots -domain domain.com
.PARAMETER domain
Mandatory - The domain to return the roots for
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the domain to return the dfs roots")]
	[String] $domain
)
$cmdResult = dfsutil /domain:$domain /view
switch ($LASTEXITCODE)
{	0
{		$rootcheck = $true
		$lineNo = 3
		$rootCollection = @()
		while ($rootcheck)
{			if (-not [string]::IsNullOrEmpty($cmdResult[$lineNo]))
{				$rootstore = "" | Select-Object domain,rootname,Path
				$rootstore.domain = $domain
				$rootstore.rootname = $cmdResult[$lineNo].trim()
				$rootstore.Path = "\\$domain\$($rootstore.rootname)"
				$rootCollection += $rootstore
				$lineNo++
			}else{$rootcheck = $false}
		}
		return $rootCollection
	}
	1168{Write-Warning "Namespace not found"}
	1355{Write-Error "Domain or Server Name not found"}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
}
function get-DFSlinks
{<#
.SYNOPSIS
Get all DFS links for a namespace
.DESCRIPTION
Get all DFS links for a namespace
Returns custom object with DFS link information if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: get-dfslinks
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get all dfs links for \\domain\Root1
get-dfslinks -Path \\domain\Root1
.EXAMPLE
Get all dfs links for \\domain\Root1 using positional parameters
get-dfslinks \\domain\Root1
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="The Path to the root to be returned")]
	[alias("Identity")]
	[String] $Path
)
$cmdResult = dfsutil /root:$Path /view
switch ($LASTEXITCODE)
{	0
{		$linkcheck = $true
		$lineNo = 5
		$linkCollection = @()
		while ($linkcheck)
{			if ($cmdResult[$lineNo] -notmatch "NOTE:")
{				if ($cmdResult[$lineNo] -match "Link Name")
{					$linkCollection += Get-DFSLink "$Path\$($cmdResult[$lineNo].Split('=')[1].Split('`"')[1])"
				}
				$lineNo++
			}else{$linkcheck = $false}
		}
		return $linkcollection
	}
	1168{Write-Warning "Namespace not found"}
	87{Write-Error "Domain or Server Name not found"}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
}


function new-DFSLink
{<#
.SYNOPSIS
Create a new dfs link
.DESCRIPTION
Create a new dfs link.
Tests to see if the share is valid, if not will error.  this can be overridden by
-force:$true
Returns custom object with DFS link information.  Returns a warning if the link
already exists. Returns $null and an error on error.
.NOTES
Function Name  	: new-dfslink
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
create dfs link \\domain\Root1\link1 with share \\server1\share1
new-dfslink -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
create dfs link \\domain\Root1\link1 with share \\server1\share1
using positional parameters
new-dfslink \\domain\Root1\link1 \\server1\share1
.EXAMPLE
force add dfs link \\domain\Root1\link1 with invalid share \\server1\share1
new-dfslink -Path \\domain\Root1\link1 -share \\server1\share1 -force:$true
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER share
Mandatory - The Path to the share
Postition 1
.PARAMETER force
Optional - Force creation of a link with an invalid share
Postition 2
.PARAMETER description
Optional - a decsription for the link
Postition 2
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Share to add as a link")]
	[string] $share,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false,HelpMessage="Force link creation with an invalid share")]
	[boolean] $force = $false,
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="a decsription for the link")]
	[string] $description#############3need to add this and change Get-DFSLink as Get-DFSRoot was changed
)
PROCESS
{	$returnvalue = $false
	try
{		if (test-fileshare $share.Split("\")[3] $share.Split("\")[2]){$create = $true}
		else
{			if ($force){$create = $true}
			else{Write-Warning "Invalid share - use -force:$true to override";$create = $false}
		}
		if ($create)
{			$cmdResult = dfsutil link add $Path $share $description
			switch ($LASTEXITCODE)
{				0	{$returnvalue = $true}
				1707{Write-Error "Domain or Server Name not found"}
				80	{Write-warning "Link already exists - use add-DFSLinkTarget to add an additional target to a link"}
				default {Write-error "command failed with error $LASTEXITCODE"}
			}
		}
	}catch{Write-Error $error[0]}
	if ($returnvalue){return Get-DFSLink $Path}
}
}
function remove-DFSLink
{<#
.SYNOPSIS
Remove a dfs link
.DESCRIPTION
Remove a dfs link.
Returns a warning if the link doesn't exists. Returns $null and an error on error.
Returns confirmation of removal if successful
.NOTES
Function Name  	: remove-dfslink
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
remove dfs link \\domain\Root1\link1
remove-dfslink -Path \\domain\Root1\link1
.EXAMPLE
remove dfs link \\domain\Root1\link1 using positional parameters
remove-dfslink \\domain\Root1\link1
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path		
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil link remove $Path
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found"}
			1168{Write-Warning "Link not found"}
			default {Write-error "command failed with error $LASTEXITCODE"}
		}
	}catch{Write-Error $error[0]}
	if ($returnvalue){Write-Host "link removed"}
}
}
function add-DFSLinkTarget
{<#
.SYNOPSIS
Add a new target to a dfs link
.DESCRIPTION
Add a new target to a dfs link
Returns a warning if the link doesn't exists. Returns $null and an error on error.
Returns confirmation of removal if successful
.NOTES
Function Name  	: add-DFSLinkTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Add target \\server1\share1 to dfs link \\domain\Root1\link1
add-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
Add target \\server1\share1 to dfs link \\domain\Root1\link1
using positional parameters
add-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
Add target \\server1\share1 to dfs link \\domain\Root1\link1, but leave disabled
add-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1 -Enabled:$true
.EXAMPLE
force add invalid target \\server1\share1 to dfs link \\domain\Root1\link1, but leave disabled
add-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1  -Enabled:$true -force:$true
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER share
Mandatory - The Path to the share
Postition 1
.PARAMETER Enabled
Optional - Specifies whether the target is enabled. Enabled by default
Postition 1
.PARAMETER force
Optional - Force creation of a link with an invalid share
Postition 3
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Share to add as a link")]
	[string] $share,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false,HelpMessage="Enable or disable the link")]
	[boolean] $enabled = $true,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$false,HelpMessage="Force link creation with an invalid share")]
	[boolean] $force = $false	
)
PROCESS
{	$returnvalue = $false
	try
{		if (test-fileshare $share.Split("\")[3] $share.Split("\")[2]){$create = $true}
		else
{			if ($force){$create = $true}
			else{Write-Warning "Invalid share - use -force:$true to override";$create = $false}
		}
		if ($create)
{			$cmdResult = dfsutil target add $Path $share
			switch ($LASTEXITCODE)
{				0	{$returnvalue = $true}
				1707{Write-Error "Domain or Server Name not found"}
				1168{Write-Warning "Link not found"}
				default {Write-error "command failed with error $LASTEXITCODE"}
			}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if (-not $enabled){ $disable = disable-dfslinktarget $Path $share}

	if ($returnvalue){return Get-DFSLink $Path}
}
}
function remove-DFSLinkTarget
{<#
.SYNOPSIS
Remove a dfs link target
.DESCRIPTION
Remove a dfs link target.
Returns a warning if the link doesn't exists. Returns $null and an error on error.
Returns the DFS link if successful
.NOTES
Function Name  	: remove-DFSLinkTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
remove dfs link target \\server1\share1 from dfs link \\domain\Root1\link1
remove-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
remove dfs link target \\server1\share1 from dfs link \\domain\Root1\link1
using positional parameters
remove-DFSLinkTarget \\domain\Root1\link1 \\server1\share1
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER share
Mandatory - The Path of the share to remove
Postition 0	
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Share to add as a link")]
	[string] $share		
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil target remove $Path $share
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found"}
			1168{Write-Warning "Link not found"}
			default {Write-error "command failed with error $LASTEXITCODE"}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){Get-DFSLink $Path}
}
}
function enable-DFSLinkTarget
{<#
.SYNOPSIS
Enable DFS link target
.DESCRIPTION
Enable DFS link target
Returns custom object with DFS link information if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: enable-DFSLinkTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Enable DFS link target \\server1\share1 on DFS link \\domain\Root1\link1
enable-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
Enable DFS link target \\server1\share1 on DFS link \\domain\Root1\link1
using positional parameters
enable-DFSLinkTarget \\domain\Root1\link1 \\server1\share1
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER share
Mandatory - The share to enable
Postition 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="Share to add as a link")]
	[string] $share
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property State online $Path $share
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found"}
			1168{Write-Error "share not found"}
			default {Write-error "command failed with error $LASTEXITCODE"}
		}

	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-DFSLink $Path}
}
}
function disable-DFSLinkTarget
{<#
.SYNOPSIS
Disable DFS link target
.DESCRIPTION
Disable DFS link target
Returns custom object with DFS link information if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: Disable-DFSLinkTarget
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Disable DFS link target \\server1\share1 on DFS link \\domain\Root1\link1
Disable-DFSLinkTarget -Path \\domain\Root1\link1 -share \\server1\share1
.EXAMPLE
Disable DFS link target \\server1\share1 on DFS link \\domain\Root1\link1
using positional parameters
Disable-DFSLinkTarget \\domain\Root1\link1 \\server1\share1
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER share
Mandatory - The share to disable
Postition 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to the DFS link")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Share to add as a link")]
	[string] $share		
)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property State offline $Path $share
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			1707{Write-Error "Domain or Server Name not found"}
			1168{Write-Error "share of link not found"}
			default {Write-error "command failed with error $LASTEXITCODE"}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-DFSLink $Path}
}
}

function add-DFSlinkABEPermission
{<#
.SYNOPSIS
Add a domain object ABE permissions to a DFS link
.DESCRIPTION
Add a domain object ABE permissions to a DFS link
Returns custom object with DFS link ABE permissions if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: add-DFSlinkABEPermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Add ABE permission for user User1 to DFS link \\domain\Root1\link1
add-DFSlinkABEPermission -Path \\domain\Root1\link1 -samaccountname User1
.EXAMPLE
Add ABE permission for group Sales to DFS link \\domain\Root1\link1
using positional parameters
add-DFSlinkABEPermission \\domain\Root1\link1 Sales
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER samaccountname
Mandatory - The samaccountname of the object to add
Postition 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to enable ABE")]
	[alias("Identity")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $samaccountname

)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property sd grant "$Path" $env:USERDOMAIN\$($samaccountname):RX Protect Replace
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			87{Write-Error "Invalid Path"}
			1332{Write-Error "invalid account"}
			default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-DFSLinkABEPermission $Path}
}
}
function remove-DFSlinkABEPermission
{<#
.SYNOPSIS
Remove a domain object ABE permissions from a DFS link
.DESCRIPTION
Remove a domain object ABE permissions from a DFS link
Returns custom object with DFS link ABE permissions if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: remove-DFSlinkABEPermission
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
remove ABE permission for user User1 from DFS link \\domain\Root1\link1
remove-DFSlinkABEPermission -Path \\domain\Root1\link1 -samaccountname User1
.EXAMPLE
remove ABE permission for group Sales from DFS link \\domain\Root1\link1
using positional parameters
remove-DFSlinkABEPermission \\domain\Root1\link1 Sales
.PARAMETER Path
Mandatory - The dfs link Path
Postition 0
.PARAMETER samaccountname
Mandatory - The samaccountname of the object to remove
Postition 1
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Path to enable ABE")]
	[alias("Identity")]
	[String] $Path,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $samaccountname

)
PROCESS
{	$returnvalue = $false
	try
{		$cmdResult = dfsutil property sd revoke "$Path" $env:USERDOMAIN\$($samaccountname) Granted
		switch ($LASTEXITCODE)
{			0	{$returnvalue = $true}
			87{Write-Error "Invalid Path"}
			1332{Write-Error "invalid account"}
			default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
		}
	}catch{Write-Error $error[0];$returnvalue = $false}
	if ($returnvalue){return Get-DFSLinkABEPermission $Path}
}
}

function new-DFSRgroup
{<#
.SYNOPSIS
Create new DFS-r Group
.DESCRIPTION
Create new DFS-r Group
Returns custom object with all DFSr group member informatnio.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: new-DFSRGroup
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new DFS-r group called rg2 using server1 and server2
with the Path to replicate being e:\data\users and a foldernname
of users.  Primary server is server1.
new-dfsrgroup -name "rg2" -description "desc1" -Servers server1,server2 -folderPath e:\data\users -foldername Users
.EXAMPLE
Create a new DFS-r group called rg2 using server1 and server2
with the Path to replicate being e:\data\users and a foldernname
of users setting the staging size to 10Gb and confilict and deleted
size to 4Gb
new-dfsrgroup -name "rg2" -description "desc1" -Servers server1,server2 -folderPath e:\data\users -foldername Users -staging size 10240 -conflictDeleteSize 4096
.PARAMETER Name
Mandatory - The Name of the Group to create
Postition 0
.PARAMETER Description
Optional - A description of the group
Postition 1
.PARAMETER Servers
Mandatory - The servers that will be members in the group.  The
first server in the list will be the primary server
Postition 2
.PARAMETER FolderPath
Optional - The Path to replicate.  If not included, the group will
be created but replication not enabled
Postition 3
.PARAMETER Foldername
Optional - The Name of the folder to appear in the group.
If not included, the group will be created but replication not enabled
Postition 4
.PARAMETER StagingSize
Optional - The size of the staging area - defaults to 4Gb
Postition 5
.PARAMETER StagingPath
Optional - The Path to the staging area - defaults to within the folder
Path.
Postition 6
.PARAMETER ConflitDeleteSize
Optional - The size of the Conflict and Deleted folder - default to 350mb
Postition 7
.PARAMETER FileFilter
Optional - The file types to exlude from replication eg "*.txt,*.tmp"
Postition 8
.PARAMETER FolderFilter
Optional - The subfolders to exclude from replication
Postition 9
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $Name,
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $description = "",
	[Parameter(Mandatory=$true,Position=2,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	$servers,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $folderPath =$null,
	[Parameter(Mandatory=$false,Position=4,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $folderName = $null,
	[Parameter(Mandatory=$false,Position=5,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[int] $StagingSize = 4096,		
	[Parameter(Mandatory=$false,Position=6,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $StagingPath = $null,
	[Parameter(Mandatory=$false,Position=7,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[int] $ConflitDeleteSize = 350,
	[Parameter(Mandatory=$false,Position=8,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $FileFilter = $null,
	[Parameter(Mandatory=$false,Position=9,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $FolderFilter = $null
)
$repgroupname = '`"' + $Name + '`"'
$repgroupdesc = '`"' + $Description + '`"'
if (-not [string]::IsNullOrEmpty($StagingPath)){$repgroupStagingPath = '`"' + $StagingPath + '`"'}
else{$repgroupStagingPath = $null}
$NewRG = "dfsradmin RG New /rgname:$repgroupname /isScheduleInLocalTime:True /rgdesc:$repgroupdesc"
$cmdResult = Invoke-Expression $NewRG
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true;Write-Host -ForegroundColor Yellow "Replication Group Container $Name Created"}
	2{Write-Error "Replication Group Already Exists";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
If ($returnvalue)
{	$SetSched = "dfsrAdmin RG Set Schedule full /rgname:$repgroupname"
	$cmdResult = Invoke-Expression $SetSched
	switch ($LASTEXITCODE)
{		0	{$returnvalue = $true;Write-Host -ForegroundColor Yellow "Schedule set to Full"}
		default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
	}
}
If ($returnvalue -and -not [string]::IsNullOrEmpty($folderName))
{	$gf = new-dfsrGroupFolder -group $Name -foldername $folderName -FileFilter $FileFilter -folderFilter $FolderFilter
	if ([string]::IsNullOrEmpty($gf)){$returnvalue = $false}
	else{$returnvalue = $true;Write-Host -ForegroundColor Yellow "Group Folder $foldername created"}
}
If ($returnvalue -and -not [string]::IsNullOrEmpty($servers))
{	$serverCount = 0
	foreach ($server in $servers){$gm = add-dfsrGroupMember -group $Name -server $server;Write-Host -ForegroundColor Yellow "$server added as memebr to Replication Group"}
	foreach ($server in $servers)
{		foreach ($server2 in $($servers | ? {$_ -ne $server})){$gc = new-dfsrGroupConnection -group $Name -source $server -destination $server2;Write-Host -ForegroundColor Yellow "Connector $server to $server2 created"}
		if (-not [string]::IsNullOrEmpty($folderName) -and -not [string]::IsNullOrEmpty($folderPath))
{			if ($servercount -eq 0){$PriServer = $true}else {$PriServer = $false}
			$en = enable-dfsrGroupMember -group $Name -server $server -primary $PriServer -foldername $folderName -folderPath $folderPath -stagingsize $StagingSize -stagingPath $StagingPath -ConflitDeleteSize $ConflitDeleteSize
			Write-Host -ForegroundColor Yellow "$server Replication Enabled"
			$serverCount ++
		}
	}
}
If ($returnvalue){return get-dfsrgroupmember $Name}
}
function remove-DFSRgroup
{<#
.SYNOPSIS
Remove a DFS-r Group
.DESCRIPTION
Remove a DFS-r Group
Returns custom object with all the DFSr group information.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: remove-DFSRGroup
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2

remove-DFSRGroup -group "rg2"
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2
using positional parameters

remove-DFSRGroup "rg2"
.PARAMETER Group
Mandatory - The Name of the Group to remove
Postition 0
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $group
)
$repgroupname = '`"' + $group + '`"'
$removeRG = "dfsradmin RG delete /rgname:$repgroupname"
$cmdResult = Invoke-Expression $removeRG
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true;Write-Host -ForegroundColor Yellow "Replication group $group removed"}
	2{Write-Error "Error removing replicaion group";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
return get-dfsrgroup
}
function get-DFSrGroup
{<#
.SYNOPSIS
Get all DFSr groups for a domain
.DESCRIPTION
Get all DFSr groups for a domain
Returns custom object with all DFSr group information if found.  Returns null and an
error if nothing found.
.NOTES
Function Name  	: get-DFSrGroup
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Get all DFS roots for domain domain.com
get-DFSrGroup -domain domain.com
.EXAMPLE
Get all DFS roots for domain domain.com using positional parameters
get-DFSrGroup domain.com
.PARAMETER domain
Optional - The domain to return the roots for. If blank, defaults
to the current logged on domain
Postition 0
#>
[CmdletBinding(ConfirmImpact="Low")]
	param
(
	[Parameter(Mandatory=$false,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the domain to return the dfs roots")]
	[String] $domain = $env:USERDNSDOMAIN
)
$cmdResult = dfsradmin RG list /domain:$domain /attr:RgName
switch ($LASTEXITCODE)
{	0
{		$groupcheck = $true
		$lineNo = 1
		$groupCollection = @()
		while ($groupcheck)
{			if (-not [string]::IsNullOrEmpty($cmdResult[$lineNo]))
{				$groupstore = "" | Select-Object groupname,domain
				$groupstore.domain = $domain
				$groupstore.groupname = $cmdResult[$lineNo].trim()
				$groupCollection += $groupstore
				$lineNo++
			}else{$groupcheck = $false}
		}
		return $GroupCollection
	}
	2{Write-Warning "$cmdResult[2]"}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
}

function get-dfsrGroupMember
{<#
.SYNOPSIS
Get all members for a DFSr group
.DESCRIPTION
Get all members for a DFSr group
Returns custom object with all DFSr group membership information
if found.  Returns null and an error if nothing found.
.NOTES
Function Name  	: get-dfsrGroupMember
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
get the members of replication group RG1
get-dfsrGroupMember -group RG1
.EXAMPLE
get the members of replication group RG1 using positional parameters
get-dfsrGroupMember RG1
.PARAMETER group
Optional - The group to return the members for.
Postition 0
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to retun members")]
	[String] $group
)
$repgroupname = '`"' + $group + '`"'
$getrg = "dfsradmin membership list /rgname:$repgroupname /attr:ALL"
return process-FixedWidthText $(Invoke-Expression $getrg)
}
function add-dfsrGroupMember
{<#
.SYNOPSIS
Add member to a DFSr group
.DESCRIPTION
Add member to a DFSr group
Returns custom object with all DFSr group membership information
if found.  Returns null and an error if nothing found.
.NOTES
Function Name  	: add-dfsrGroupMember
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Add server1 as a member to replication group RG1
get-dfsrGroupMember -group RG1 -server server1
.EXAMPLE
Add server1 as a member to replication group RG1 using positional parameters
get-dfsrGroupMember RG1 server1
.PARAMETER group
Mandatory - The Name of the group to add the member
Postition 0
.PARAMETER server
Mandatory - The Name of the server to add to the group
Postition 0
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to add member")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of Server to Add")]
	[String] $server
)
$repgroupname = '`"' + $group + '`"'
$newmember = "dfsradmin member new /rgname:$repgroupname /memname:$server"
$cmdResult = Invoke-Expression $newmember
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Add member failed)";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupMember $group}
}
function remove-dfsrGroupMember
{<#
.SYNOPSIS
Remove member from a DFSr group
.DESCRIPTION
Remove member from a DFSr group
Returns custom object with all DFSr group membership information
if found.  Returns null and an error if nothing found.
.NOTES
Function Name  	: remove-dfsrGroupMember
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Remove server1 as a member from replication group RG1
remove-dfsrGroupMember -group RG1 -server server1
.EXAMPLE
Remove server1 as a member from replication group RG1 using positional parameters
remove-dfsrGroupMember RG1 server1
.PARAMETER group
Mandatory - The Name of the group to remove the member
Postition 0
.PARAMETER server
Mandatory - The Name of the server to remove from the group
Postition 0
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to add member")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of Server to Remove")]
	[String] $server
)
$repgroupname = '`"' + $group + '`"'
$removemember = "dfsradmin member delete /rgname:$repgroupname /memname:$server"
$ret = Invoke-Expression $removemember
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Remove member failed)";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupMember $group}
}
function enable-dfsrGroupMember
{<#
.SYNOPSIS
Enable a member of a replication group
.DESCRIPTION
Enable a member of a replication group
Returns custom object with all DFSr group member information.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: enable-dfsrGroupMember
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
enable member server1 of a DFS-r group called rg2 with the
Path to replicate being e:\data\users and a foldernname
of users.

enable-dfsrGroupMember -group "rg2" -Server server1 -folderPath e:\data\users -foldername Users
.EXAMPLE
enable member server1 of a DFS-r group called rg2
with the Path to replicate being e:\data\users and a foldernname
of users setting the staging size to 10Gb and confilict and deleted
size to 4Gb

enable-dfsrGroupMember -group "rg2"  -Server server1 -folderPath e:\data\users -foldername Users -staging size 10240 -conflictDeleteSize 4096
.PARAMETER group
Mandatory - The Name of the Group to add a server
Postition 0
.PARAMETER Server
Mandatory - The server to enable
Postition 1
.PARAMETER Primary
Optional - Indicates whether the server is the primary server
Boolean value which defaults to false
Postition 2
.PARAMETER FolderPath
Mandatory - The Path to replicate.
Postition 3
.PARAMETER Foldername
Mandatory - The Name of the folder to enable the server in.
Postition 4
.PARAMETER StagingSize
Optional - The size of the staging area - defaults to 4Gb
Postition 5
.PARAMETER StagingPath
Optional - The Path to the staging area - defaults to within the folder
Path.
Postition 6
.PARAMETER ConflitDeleteSize
Optional - The size of the Conflict and Deleted folder - default to 350mb
Postition 7
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to add member")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of Server to Remove")]
	[String] $server,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false,HelpMessage="Is this the primary server")]
	[boolean] $Primary = $false,
	[Parameter(Mandatory=$true,Position=3,ValueFromPipeline=$false,HelpMessage="Path to the folder to enable")]
	[string] $folderPath,
	[Parameter(Mandatory=$true,Position=4,ValueFromPipeline=$false,HelpMessage="Replication folder Name")]
	[string] $folderName,
	[Parameter(Mandatory=$false,Position=5,ValueFromPipeline=$false,HelpMessage="Staging size in Mb")]
	[int] $StagingSize = 4096,		
	[Parameter(Mandatory=$false,Position=6,ValueFromPipeline=$false,HelpMessage="Path to Staging folder")]
	[string] $StagingPath = $null,
	[Parameter(Mandatory=$false,Position=7,ValueFromPipeline=$false,HelpMessage="Confict and deleted folder size in Mb")]
	[int] $ConflitDeleteSize = 350
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$repgroupfolderPath = '`"' + $folderPath + '`"'
$enablemember = "dfsradmin Membership Set /RgName:$repgroupname /RfName:$repgroupfolderName /MemName:$server /LocalPath:$repgroupfolderPath /MembershipEnabled:true  /StagingSize:$StagingSize /CDSize:$ConflitDeleteSize"
if (-not [string]::IsNullOrEmpty($repgroupStagingPath)){$enablemember += " /StagingPath:$repgroupStagingPath"}
if ($Primary){$enablemember += " /IsPrimary:true"}
else{$enablemember += " /IsPrimary:false"}
$cmdResult = Invoke-Expression $enablemember
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "enable member error - $server";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupMember $group}
}
function disable-dfsrGroupMember
{<#
.SYNOPSIS
Disables replication for a server in a Replication group
.DESCRIPTION
Disables replication for a server in a Replication group
Returns custom object with all DFSr group member information.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: disable-dfsrGroupMember
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
disable server1 in DFS-r group rg2 folder Name Users

disable-dfsrGroupMember -group "rg2" -Server server1 -foldername Users
.EXAMPLE
disable server1 in DFS-r group rg2 folder Name Users using positional
parameters
disable-dfsrGroupMember "rg2" server1 Users
.PARAMETER group
Mandatory - The Name of the Group to disable the server
Postition 0
.PARAMETER Server
Mandatory - The server to diable
Postition 1
.PARAMETER Foldername
Mandatory - The Name of the folder to disable the server from
Postition 2
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to add member")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of Server to Remove")]
	[String] $server,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$false,HelpMessage="Replication folder Name")]
	[string] $folderName
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$disablemember = "dfsradmin Membership Set /RgName:$repgroupname /RfName:$repgroupfolderName /MemName:$server /MembershipEnabled:$false"
$cmdResult = Invoke-Expression $disablemember
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "enable member error - $server";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupMember $group}
}

function new-dfsrGroupConnection
{<#
.SYNOPSIS
Create a new replication connection between 2 members of a replication group
.DESCRIPTION
Create a new replication connection between 2 members of a replication group
Returns custom object with all DFSr group connection information.
Returns null and an error if errors were encounterd.
.NOTES
Function Name  	: new-dfsrGroupConnection
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
create a new connection between server1 and server2 in group RG2

new-dfsrGroupConnection -group "rg2" -source server1 -destination server2
.EXAMPLE
create a new connection between server1 and server2 in group RG2
using positional parameters

new-dfsrGroupConnection "rg2" server1 server2
.PARAMETER group
Mandatory - The Name of the Group to remoe the server from
Postition 0
.PARAMETER Source
Mandatory - The source server for the connection
Postition 1
.PARAMETER Destination
Mandatory - The destination server for the connection
Postition 2
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to add connection")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of source Server")]
	[String] $source,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="Name of destination Server")]
	[String] $destination
)
$repgroupname = '`"' + $group + '`"'
$keywords = '`"' + "From $source to $destination" + '`"'
$newconn = "dfsradmin conn new /rgname:$repgroupname /SendMem:$source /RecvMem:$destination /ConnEnabled:true /ConnKeywords:$keywords"
$cmdResult = Invoke-Expression $newconn
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Add connection - Server not found";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupConnection -group $group}
}
function get-dfsrGroupConnection
{<#
.SYNOPSIS
Get all connections for a replication group
.DESCRIPTION
Get all connections for a replication group
Returns custom object with all DFSr group connection information
if found.  Returns null and an error if nothing found.
.NOTES
Function Name  	: get-dfsrGroupConnection
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
get the conectionns of replication group RG1

get-dfsrGroupConnection -group RG1
.EXAMPLE
get the connections of replication group RG1 using positional parameters

get-dfsrGroupConnection RG1
.PARAMETER group
Mandatory - The group Name  to return the connections for.
Postition 0
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to retun members")]
	[String] $group
)
$repgroupname = '`"' + $group + '`"'
$getfolder = "dfsradmin conn list /rgname:$repgroupname"
return process-FixedWidthText $(Invoke-Expression $getfolder)
}
function remove-dfsrGroupConnection
{<#
.SYNOPSIS
Removes a replication connection between 2 members of a replication group
.DESCRIPTION
Removes a replication connection between 2 members of a replication group
Returns custom object with all DFSr group connection information.
Returns null and an error if errors were encounterd.
.NOTES
Function Name  	: remove-dfsrGroupConnection
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Remove a connection between server1 and server2 in group RG2

remove-dfsrGroupConnection -group "rg2" -source server1 -destination server2
.EXAMPLE
remove a connection between server1 and server2 in group RG2
using positional parameters

remove-dfsrGroupConnection "rg2" server1 server2
.PARAMETER group
Mandatory - The Name of the Group to remove the connection from
Postition 0
.PARAMETER Source
Mandatory - The source server for the connection
Postition 1
.PARAMETER Destination
Mandatory - The destination server for the connection
Postition 2
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to remove connection")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$true,HelpMessage="Name of source Server")]
	[String] $source,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="Name of destination Server")]
	[String] $destination
)
$repgroupname = '`"' + $group + '`"'
$newconn = "dfsradmin conn delete /rgname:$repgroupname /SendMem:$source /RecvMem:$destination"
$cmdResult = Invoke-Expression $newconn
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Add connection - Server not found";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-dfsrGroupConnection -group $group}
}

function new-dfsrGroupFolder
{<#
.SYNOPSIS
Create new DFS-r Group folder
.DESCRIPTION
Create new DFS-r Group folder
Returns custom object with all the DFSr group folder information.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: new-DFSrGroupFolder
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2

new-DFSrGroupFolder -group "rg2" -foldername Users
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2
using positional parameters
new-DFSrGroupFolder "rg2"  Users
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2
with exclude file filter for pst and mdb files
and exclude subfolder filter for folders named backup

new-DFSrGroupFolder -group "rg2" -foldername Users -filefilter "*.pst,*.mdb" -folderfilter "backup"
.PARAMETER Group
Mandatory - The Name of the Group to create the folder in
Postition 0
.PARAMETER Foldername
Mandatory - The Name of the folder to appear in the group.
Postition 1
.PARAMETER FileFilter
Optional - The file types to exlude from replication eg "*.txt,*.tmp"
Postition 2
.PARAMETER FolderFilter
Optional - The subfolders to exclude from replication
Postition 3
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $folderName,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $FileFilter,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$false,HelpMessage="samaccountname notation of the ID to allow access")]
	[string] $FolderFilter
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$repgroupfilefilter = '`"' + $filefilter + '`"'
$repgroupfolderfilter = '`"' + $folderfilter + '`"'
$repgroupfolderPath = '`"' + $folderPath + '`"'

$rfname = "dfsradmin RF New /rgName:$repgroupname /RfName:$repgroupfolderName /RfFileFilter:$repgroupfilefilter /RfDirFilter:$repgroupfolderfilter"
$cmdResult = Invoke-Expression $rfname
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Add Folder - Folder Already Exists";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-DFSRGroupfolder -group $group}	
}
function get-DFSRGroupfolder
{<#
.SYNOPSIS
Get DFS-r group folders
.DESCRIPTION
Get DFS-r group folders
Returns custom object with all DFSr group connection information
if found.  Returns null and an error if nothing found.
.NOTES
Function Name  	: get-dfsrGroupFolder
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
get the conectionns of replication group RG1

get-dfsrGroupFolder -group RG1
.EXAMPLE
get the connections of replication group RG1 using positional parameters

get-dfsrGroupFolder RG1
.PARAMETER group
Mandatory - The group Name to return the group(s) for.
Postition 0
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to retun members")]
	[String] $group
)
$repgroupname = '`"' + $group + '`"'
$getfolder = "dfsradmin rf list /rgname:$repgroupname /attr:`"RfName,RfDesc,RfDfsPath,RfFileFilter,RfDirFilter`""
return process-FixedWidthText $(Invoke-Expression $getfolder)
}
function remove-DFSRGroupfolder
{<#
.SYNOPSIS
Remove a DFS-r Group folder
.DESCRIPTION
Remove a DFS-r Group folder
Returns custom object with all the DFSr group folder information.  Returns null and an
error if errors were encounterd.
.NOTES
Function Name  	: remove-DFSRGroupfolder
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2

remove-DFSRGroupfolder -group "rg2" -foldername Users
.EXAMPLE
Create a new DFS-r group folder caller users in group rg2
using positional parameters

remove-DFSRGroupfolder "rg2" Users
.PARAMETER Group
Mandatory - The Name of the Group to remove the folder from
Postition 0
.PARAMETER Foldername
Mandatory - The Name of the folder to remove from the group.
Postition 1
#>
	param
(
	[Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$true,HelpMessage="Name of group to remove folder")]
	[String] $group,
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="Name of folder to remove")]
	[string] $folderName
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$removefolder = "dfsradmin rf delete /rgname:$repgroupname /RfName:$repgroupfolderName"
$cmdResult = Invoke-Expression $removefolder
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Remove folder failed";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
if ($returnvalue){return get-DFSRGroupfolder -group $group}	
}

function new-dfsrPropagationTest
{<#
.SYNOPSIS
Create a new propagation test for a replication group
.DESCRIPTION
Create a new propagation test for a replication group
Returns true or false - with information message
.NOTES
Function Name  	: new-dfsrPropagationTest
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new propagation test on folder caller users in group rg2
on server server1

new-dfsrPropagationTest -group "rg2" -foldername Users -server server1
.EXAMPLE
Create a new propagation test on folder caller users in group rg2
on server server1 using positional parameters

new-dfsrPropagationTest "rg2" Users server1
.PARAMETER Group
Mandatory - The Name of the Group to run the test on
Postition 0
.PARAMETER Foldername
Mandatory - The Name of the folder to run the test on.
Postition 1
.PARAMETER server
Mandatory - The Name of the server to run the on.
Postition 1
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$false,HelpMessage="Folder Name to test against")]
	[string] $folderName,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="Name of Server to run test against")]
	[String] $server
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$proptest = "dfsradmin proptest new /rgname:$repgroupname /rfname:$repgroupfolderName /memname:$server"
$cmdResult = Invoke-Expression $proptest
switch ($LASTEXITCODE)
{	0	{write-host "Propagation test completed successfully";$returnvalue = $true}
	2{Write-Error "Propagation test failed";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
return $returnvalue
}
function remove-dfsrPropagationTest
{<#
.SYNOPSIS
Create a new propagation test for a replication group
.DESCRIPTION
Create a new propagation test for a replication group
Returns true or false - with information message
.NOTES
Function Name  	: remove-dfsrPropagationTest
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Remove propagation tests on folder caller users in group rg2
on server server1

remove-dfsrPropagationTest -group "rg2" -foldername Users -server server1
.EXAMPLE
Remove propagation tests on folder caller users in group rg2
on server server1 using positional parameters

remove-dfsrPropagationTest "rg2" Users server1
.EXAMPLE
Remove propagation tests on folder caller users in group rg2
on server server1 that are older than 10 days

remove-dfsrPropagationTest -group "rg2" -foldername Users -server server1 -age 10
.PARAMETER Group
Mandatory - The Name of the Group to remove the test from
Postition 0
.PARAMETER Foldername
Mandatory - The Name of the folder to remove the test from.
Postition 1
.PARAMETER server
Mandatory - The Name of the server to remove the test from.
Postition 1
.PARAMETER age
Optional - the age of the reports to delete in days - defauls to 5 days.
Postition 1
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $group,
	[Parameter(Mandatory=$True,Position=1,ValueFromPipeline=$false,HelpMessage="Folder Name to remove the tests from")]
	[string] $folderName,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="Name of Server to remove tests from")]
	[String] $server,
	[Parameter(Mandatory=$false,Position=3,ValueFromPipeline=$true,HelpMessage="The age in days of the tests to remove - defaults to 5")]
	[int] $age = 5
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$proptest = "dfsradmin proptest clean /rgname:$repgroupname /rfname:$repgroupfolderName /memname:$server /age:$age"
$cmdResult = Invoke-Expression $proptest
switch ($LASTEXITCODE)
{	0	{write-host "Propagation test removed successfully";$returnvalue = $true}
	2{Write-Error "Propagation test failed";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
}
function new-dfsrPropagationReport
{<#
.SYNOPSIS
Create a new propagation report for a replication group
.DESCRIPTION
Create a new propagation report for a replication group
Returns a custom object with the report Name and the Path to the report.
return Null and and error if an error was encountered
.NOTES
Function Name  	: new-dfsrPropagationReport
Author     		: Adam Stone
Requires   		: PowerShell V2
.LINK
http://adadmin.blogspot.com
.EXAMPLE
Create a new propagation report on folder caller users in group rg2
on server server1 with report Name NewReport

new-dfsrPropagationReport -group "rg2" -foldername Users -server server1 -reportname NewReport
.EXAMPLE
Create a new propagation test on folder caller users in group rg2
on server server1 using positional parameters

new-dfsrPropagationReport "rg2" Users server1 NewReport
.EXAMPLE
Create a new propagation report on folder caller users in group rg2
on server server1 with report Name NewReport using only the last 5 files

new-dfsrPropagationReport -group "rg2" -foldername Users -server server1 -reportname NewReport -NumberofFiles 5
.PARAMETER Group
Mandatory - The Name of the Group to run the report on
Postition 0
.PARAMETER Foldername
Mandatory - The Name of the folder to run the report on.
Postition 1
.PARAMETER server
Mandatory - The Name of the server to run the report on.
Postition 3
.PARAMETER reportname
Mandatory - The Name of the report to generate.
Postition 4
.PARAMETER NumberOfFiles
Optional - number of files to use in the report, defaults to all files.
Postition 5
#>
	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Name of the DFSRgroup")]
	[String] $group,
	[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Folder Name to test against")]
	[string] $folderName,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="Name of Server to run test against")]
	[String] $server,
	[Parameter(Mandatory=$True,Position=2,ValueFromPipeline=$true,HelpMessage="The Name of the report that will be generated")]
	[String] $ReportName,		
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$false,HelpMessage="number of files to use in the report, defaults to all files")]
	[Int] $NumberofFiles = 0
)
$repgroupname = '`"' + $group + '`"'
$repgroupfolderName = '`"' + $FolderName + '`"'
$repgroupReportName = '`"' + $ReportName + '`"'
$proptest = "dfsradmin proprep new /rgname:$repgroupname /rfname:$repgroupfolderName /memname:$server /nf:$NumberofFiles /repname:$repgroupReportName"
$cmdResult = Invoke-Expression $proptest
switch ($LASTEXITCODE)
{	0	{$returnvalue = $true}
	2{Write-Error "Propagation test failed";$returnvalue = $false}
	default {Write-error "command failed with error $LASTEXITCODE";$returnvalue = $false}
}
$Report = "" | Select-Object Name,Path
$Report.Name = $ReportName
$Report.Path = "$(pwd)\$ReportName.html"
return $report
}

#endregion DFS/DFS-R Functions

function process-FixedWidthText
{	param
(
	[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,HelpMessage="Text input to process")]
	[array]$In,
	[Parameter(Mandatory=$false,Position=1,ValueFromPipeline=$true,HelpMessage="Line number to start processing content")]
	[int] $Lineno = 1,
	[Parameter(Mandatory=$false,Position=2,ValueFromPipeline=$true,HelpMessage="Text to find to stop processing - defaults to empty line")]
	$EndText = $null
)
$vars = @()
$string = $in[0]
While ($string -match " ")
{	$Var = "" | Select-Object "Name","Length","ColWidth"
	$length = $string.length
	$Var.length = $string.indexof(" ")
	$newlength = $($string.length - $($Var.length))
	$Var.Name = $string.substring(0,$($Var.length)).trim()
	$string = $string.substring($($Var.length),$newlength).trim()
	$Var.colwidth = $length - $string.length
	$vars += $var

}
$collection = @()
$textcheck = $true
while ($textcheck)
{	if ($EndText -eq $null)
{		if (-not [string]::IsNullOrEmpty($in[$lineNo])){$Linefound = $false}
		else{$Linefound = $true}
	}else
{		if ($in[$lineNo] -notmatch $endtext){$Linefound = $false}
		else{$Linefound = $true}
	}
	if (-not $Linefound)
{		$array = @()
		foreach ($Var in $vars){$array += $($Var.Name)}
		$store = "" | Select-Object $array
		$string = $in[$lineno]
		foreach ($var in $vars)
{			$store.$($Var.Name) = $string.substring(0,$($Var.colwidth)).trim()
			$string = $string.substring($($Var.colwidth),$($string.length - $($Var.colwidth)))
		}
		$lineNo ++
		$collection += $store
	}else {$textcheck = $false}
}
return $collection
}
New-Alias -Name list-DFSLinks -Value get-DFSlinks
New-Alias -Name list-DFSroots -Value get-DFSroots


